﻿using System;
using System.IO;
using System.Text;
using Codeplex.Data;

namespace HashMapper.SerializeProvider.Protobuf
{
    public class ProtobufSerializeProvider : ISerializeProvider
    {
        public byte[] Serialize(Type type, object obj)
        {
            var parser = GetNumberParser(type);
            if (parser != null) return Encoding.UTF8.GetBytes(obj.ToString());

            using (var ms = new MemoryStream())
            {
                ProtoBuf.Serializer.NonGeneric.Serialize(ms, obj);
                return ms.ToArray();
            }
        }

        public object Deserialize(Type type, byte[] bytes)
        {
            var parser = GetNumberParser(type);
            if (parser != null) return parser(Encoding.UTF8.GetString(bytes));

            using (var ms = new MemoryStream(bytes))
            {
                return ProtoBuf.Serializer.NonGeneric.Deserialize(type, ms);
            }
        }

        Func<string, object> GetNumberParser(Type type)
        {
            switch (Type.GetTypeCode(type))
            {
                case TypeCode.Int16:
                    return s => Int16.Parse(s);
                case TypeCode.Int32:
                    return s => Int32.Parse(s);
                case TypeCode.Int64:
                    return s => Int64.Parse(s);
                case TypeCode.UInt16:
                    return s => UInt16.Parse(s);
                case TypeCode.UInt32:
                    return s => UInt32.Parse(s);
                case TypeCode.UInt64:
                    return s => UInt64.Parse(s);
                default:
                    return null;
            }
        }
    }
}